//
// Created by hay boy on 2022/7/30.
//

#ifndef ALGORITHMS_ARRAYCHAINS_H
#define ALGORITHMS_ARRAYCHAINS_H
#include <iostream>
#include <sstream>
#include "../chainNode/ChainNode.h"

using namespace std;
template<class T>
struct tort{
    int first;
    T second;
    tort(int theFirst,const T& theSecond){
        first = theFirst;
        second = theSecond;
    }
};
template<class T>
class arrayChain{
protected:
    tort<T*>* array;
    ChainNode<T> chain;
    int arrayLength;
    int arraySize;
public:
    explicit arrayChain(int initialCapacity = 10);
    bool empty();
    int size();
    void clear();
    T& get(int theIndex);
    int indexOf(const T& theElement);
    void erase();
    void insert(const T& theElement);
};

template<class T>
arrayChain<T>::arrayChain(int initialCapacity) {
    if(initialCapacity<=0){
        ostringstream s;
        s<<"initialCapacity must be >0 ";
        throw illegalParameterValue(s.str());
    }
    array = new tort<T*>[initialCapacity];
    arraySize = 0;
    arrayLength = initialCapacity;
    chain = nullptr;
}

template<class T>
bool arrayChain<T>::empty() {
    return arraySize == 0;
}

template<class T>
int arrayChain<T>::size() {
    return arraySize;
}

template<class T>
void arrayChain<T>::clear() {
    delete[] array;
    ChainNode<T> next = nullptr;
    while(chain!= nullptr){
        next = chain.next;
        delete chain;
        chain = next;
    }
    arraySize = 0;
}

template<class T>
void arrayChain<T>::insert(const T &theElement) {
    if(arraySize == 0){
        auto* chainNode = new ChainNode<T>(theElement);
        array[0] = tort<T*>(0,chainNode);
        chain = chainNode;
    }
    if(arraySize==arrayLength){
        arrayLength *= 2;
        auto newArray = new tort<T*>[arrayLength];
        copy(array,array+arraySize,newArray);
        delete []array;
        array = newArray;
    }

    arraySize++;
}

template<class T>
T &arrayChain<T>::get(int theIndex) {

}

template<class T>
int arrayChain<T>::indexOf(const T &theElement) {
    return 0;
}

template<class T>
void arrayChain<T>::erase() {

}

#endif //ALGORITHMS_ARRAYCHAINS_H
